﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

namespace AzureSASGenerator
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();

            this.dtpSASStartDate.Value = DateTime.Now;
            this.dtpSASStartDate.MinDate = DateTime.Now;
            this.dtpSASEndDate.MinDate = DateTime.Now.AddMinutes(1);
            this.dtpSASEndDate.Value = DateTime.Now.AddMinutes(1);

            ToolTip ttInvalidStorageName = new ToolTip();
            ttInvalidStorageName.SetToolTip(this.btnInvalidStorageName, "You must enter a the name of a valid storage account.");

            ToolTip ttInvalidStorageKey = new ToolTip();
            ttInvalidStorageKey.SetToolTip(this.btnInvalidStorageKey, "You must enter a valid storage key.");
        }

        private CloudStorageAccount GetCloudStorageAccount
        {
            get
            {
                // The connection string for the storage account.  Modify for your account.
                string storageConnectionString =
                   "DefaultEndpointsProtocol=https;" +
                   "AccountName=" + this.txtStorageAccountName.Text + ";" +
                   "AccountKey=" + this.txtStorageAccountKey.Text + ";";

                try
                {
                    // Create the storage account with the connection string.
                    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnectionString);
                    return storageAccount;
                }
                catch (Exception ex) { throw ex; }
            }
        }

        private CloudBlobClient GetCloudBlobClient
        {
            get
            {
                try
                {
                    CloudBlobClient blobClient = this.GetCloudStorageAccount.CreateCloudBlobClient();
                    //container.CreateIfNotExists();

                    return blobClient;
                }
                catch (Exception ex) { throw ex; }
            }
        }

        private CloudBlobContainer GetVHDBlobContainer
        {
            get 
            {
                try
                {
                    // Get a reference to the container which contains the VHDs
                    CloudBlobContainer container = this.GetCloudBlobClient.GetContainerReference("vhds");

                    return container;
                }
                catch (Exception ex) { throw ex; }
            }
        }

        private void cmbBlobs_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.cmbBlobs.SelectedIndex >= 0)
            {
                this.btnGoTo2.Enabled = true;
            }
        }

        private void chkNoStartTime_CheckedChanged(object sender, EventArgs e)
        {
            this.dtpSASStartDate.Enabled = !this.chkNoStartTime.Checked;
        }

        private string GetSASForBlob(CloudPageBlob blob, SharedAccessBlobPermissions permission)
        {
            var sas = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
            {
                Permissions = permission,
                SharedAccessStartTime = (this.chkNoStartTime.Checked ? DateTime.UtcNow.AddMinutes(-5) : this.dtpSASStartDate.Value.ToUniversalTime().AddMinutes(-5)),
                SharedAccessExpiryTime = this.dtpSASEndDate.Value.ToUniversalTime(),
            });

            return string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}{1}", blob.Uri, sas);
        }

        private void btnOKBlobs_Click(object sender, EventArgs e)
        {
            // Create a List to store our KeyValuePairs
            List<KeyValuePair<string, string>> data = new List<KeyValuePair<string, string>>();

            try 
            {
                // Add data to the List
                foreach (var blobItem in this.GetVHDBlobContainer.ListBlobs())
                {
                    data.Add(new KeyValuePair<string, string>(blobItem.Uri.ToString(), blobItem.Uri.ToString().Substring(blobItem.Uri.ToString().LastIndexOf("/") + 1)));
                }

                // Clear the combobox
                this.cmbBlobs.DataSource = null;
                this.cmbBlobs.Items.Clear();

                // Bind the combobox
                this.cmbBlobs.DataSource = new BindingSource(data, null);
                this.cmbBlobs.DisplayMember = "Value";
                this.cmbBlobs.ValueMember = "Key";
            }
            catch (Exception ex)
            {
                ShowErrorPanel(ex);
            }
        }

        private void ShowErrorPanel(Exception ex)
        {
            this.pnlError.Visible = true;
            this.txtErrorText.Text = ex.Message.ToString();
        }

        private bool ValidateInputEntry()
        {
            this.btnInvalidStorageKey.Visible = (this.txtStorageAccountKey.Text.Length <= 0);
            this.btnInvalidStorageName.Visible = (this.txtStorageAccountName.Text.Length <= 0);

            return !(this.txtStorageAccountName.Text.Length == 0 || this.txtStorageAccountKey.Text.Length == 0);
        }

        private void btnGoTo2_Click(object sender, EventArgs e)
        {
            if (this.ValidateInputEntry())
            {
                // Create a List to store our KeyValuePairs
                List<KeyValuePair<string, string>> data = new List<KeyValuePair<string, string>>();

                try
                {
                    // Add data to the List
                    foreach (var blobItem in this.GetVHDBlobContainer.ListBlobs())
                    {
                        data.Add(new KeyValuePair<string, string>(blobItem.Uri.ToString(), blobItem.Uri.ToString().Substring(blobItem.Uri.ToString().LastIndexOf("/") + 1)));
                    }

                    // Clear the combobox
                    this.cmbBlobs.DataSource = null;
                    this.cmbBlobs.Items.Clear();

                    // Bind the combobox
                    this.cmbBlobs.DataSource = new BindingSource(data, null);
                    this.cmbBlobs.DisplayMember = "Value";
                    this.cmbBlobs.ValueMember = "Key";
                }
                catch (Exception ex)
                {
                    ShowErrorPanel(ex);
                }

                this.pnlBlobSelection.Location = new Point(46, 12);
                this.pnl1Label.Visible = true;
                this.pnl2Label.Visible = false;
                this.pnlInput.Visible = false;
                AnimationUtility.Animate(this.pnlBlobSelection, AnimationUtility.Effect.Slide, 1000, 360);
            }
        }

        private void btnGoTo1_Click(object sender, EventArgs e)
        {
            this.pnlInput.Location = new Point(12, 12);
            this.pnl2Label.Location = new Point(562, 12);
            this.pnl1Label.Visible = false;
            this.pnl2Label.Visible = true;
            this.pnlBlobSelection.Visible = false;
            this.pnlResult.Visible = false;
            AnimationUtility.Animate(this.pnlInput, AnimationUtility.Effect.Slide, 1000, 180);
        }

        private void btnGoTo3_Click(object sender, EventArgs e)
        {
            if (this.dtpSASEndDate.Value > this.dtpSASStartDate.Value)
            {
                SharedAccessBlobPermissions permission = SharedAccessBlobPermissions.Read;

                CloudPageBlob selectedBlob = null;

                foreach (CloudPageBlob blob in this.GetVHDBlobContainer.ListBlobs())
                {
                    if (blob.Uri.ToString().Contains(this.cmbBlobs.SelectedText))
                    {
                        selectedBlob = blob;
                        break;
                    }
                }

                this.txtSASURL.Text = GetSASForBlob(selectedBlob, permission);
            }

            this.pnlInput.Visible = false;
            this.pnlInput.Location = new Point(80, 12);
            this.pnlBlobSelection.Visible = false;
            this.pnl1Label.Visible = true;
            this.pnl2Label.Location = new Point(46, 12);
            this.pnl2Label.Visible = true;
            this.pnl3Label.Visible = false;
            AnimationUtility.Animate(this.pnlResult, AnimationUtility.Effect.Slide, 1000, 360);
        }

        private void btnDone_Click(object sender, EventArgs e)
        {
            this.pnlInput.Location = new Point(12, 12);
            this.pnl1Label.Visible = false;
            this.pnl2Label.Location = new Point(562, 12);
            this.pnl2Label.Visible = true;
            this.pnl3Label.Visible = true;
            this.pnlBlobSelection.Visible = false;
            this.pnlResult.Visible = false;
            this.ResetControls(true);
            AnimationUtility.Animate(this.pnlInput, AnimationUtility.Effect.Slide, 1000, 180);
        }

        private void btnGoBackTo2_Click(object sender, EventArgs e)
        {
            this.pnlBlobSelection.Location = new Point(46, 12);
            this.pnl1Label.Visible = true;
            this.pnl2Label.Visible = false;
            this.pnl3Label.Visible = true;
            this.pnlResult.Visible = false;
            AnimationUtility.Animate(this.pnlBlobSelection, AnimationUtility.Effect.Slide, 1000, 360);
            this.pnlInput.Visible = false;
            this.ResetControls();
        }

        private void ResetControls(bool resetKeys = false)
        {
            this.btnCopySASURL.BackColor = Color.FromKnownColor(KnownColor.Control);
            this.txtSASURL.BackColor = Color.FromKnownColor(KnownColor.Control);
            if (resetKeys)
            {
                this.txtStorageAccountKey.Text = string.Empty;
                this.txtStorageAccountName.Text = string.Empty;
                this.txtSASURL.Text = string.Empty;
            }
        }

        private void btnCopySASURL_Click(object sender, EventArgs e)
        {
            if (this.txtSASURL.Text.Length > 0)
            {
                this.txtSASURL.SelectAll();
                this.txtSASURL.Copy();
                string txtPreserveText = this.txtSASURL.Text;
                this.txtSASURL.Text = "Copied";
                this.txtSASURL.TextAlign = HorizontalAlignment.Center;
                this.txtSASURL.BackColor = Color.Azure;
            }
        }

        protected void btnCopySASURL_MouseHover(object sender, EventArgs e)
        {
            this.btnCopySASURL.Image = new Bitmap(Properties.Resources.icon_copy_hover);
        }

        protected void btnCopySASURL_MouseLeave(object sender, EventArgs e)
        {
            this.btnCopySASURL.Image = new Bitmap(Properties.Resources.icon_copy);
        }

        protected void btnDone_MouseHover(object sender, EventArgs e)
        {
            this.btnDone.Image = new Bitmap(Properties.Resources.fx_dialog_ok_hover);   
        }

        protected void btnDone_MouseLeave(object sender, EventArgs e)
        {
            this.btnDone.Image = new Bitmap(Properties.Resources.fx_dialog_ok);
        }

        protected void btnGoTo2_MouseHover(object sender, EventArgs e) 
        {
            this.btnGoTo2.Image = new Bitmap(Properties.Resources.button_next_hover);
        }

        protected void btnGoTo2_MouseLeave(object sender, EventArgs e) 
        {
            this.btnGoTo2.Image = new Bitmap(Properties.Resources.button_next);
        }

        protected void btnGoTo3_MouseHover(object sender, EventArgs e)
        {
            this.btnGoTo3.Image = new Bitmap(Properties.Resources.button_next_hover);
        }

        protected void btnGoTo3_MouseLeave(object sender, EventArgs e)
        {
            this.btnGoTo3.Image = new Bitmap(Properties.Resources.button_next);
        }

        protected void btnGoBackTo2_MouseHover(object sender, EventArgs e)
        {
            this.btnGoBackTo2.Image = new Bitmap(Properties.Resources.button_back_hover);
        }

        protected void btnGoBackTo2_MouseLeave(object sender, EventArgs e)
        {
            this.btnGoBackTo2.Image = new Bitmap(Properties.Resources.button_back);
        }

        protected void btnGoTo1_MouseHover(object sender, EventArgs e)
        {
            this.btnGoTo1.Image = new Bitmap(Properties.Resources.button_back_hover);
        }

        protected void btnGoTo1_MouseLeave(object sender, EventArgs e)
        {
            this.btnGoTo1.Image = new Bitmap(Properties.Resources.button_back);
        }

        private void btnErrorOK_Click(object sender, EventArgs e)
        {
            this.pnlInput.Location = new Point(12, 12);
            this.pnl1Label.Visible = false;
            this.pnl2Label.Location = new Point(562, 12);
            this.pnl2Label.Visible = true;
            this.pnl3Label.Visible = true;
            this.pnlBlobSelection.Visible = false;
            this.pnlResult.Visible = false;
            this.ResetControls(true);
            AnimationUtility.Animate(this.pnlInput, AnimationUtility.Effect.Slide, 1000, 180);
            this.pnlError.Visible = false;
            this.txtErrorText.Text = string.Empty;
        }
    }
}
